home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HyperLib 1997 Winter - Disc 1
/
HYPERLIB-1997-Winter-CD1.ISO.7z
/
HYPERLIB-1997-Winter-CD1.ISO
/
オンラインウェア
/
UTIL
/
Acme Filters 2.3.2 folder.sit
/
Acme Filters 2.3.2 folder
/
Acme Filters 2.3.2
/
Acme Filters オ
/
Sources
/
Acme Filters.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-03-02
|
33KB
|
1,237 lines
/**********************************************************************************************
* Program Name: Acme Filters
*
* Module Name: Acme Filters.c
*
* Description: Convert Donna's word processor files to Mac files.
*
* Author: Eric V. Curtis
*
* History:
* v1.0.0 08-Mar-1995 Created.
* v1.1.0 09-Mar-1995 Added old-style drag & drop processing of text files.
* v1.2.0 22-Mar-1995 Added rot13 support, Cancel(), and SpinCursor().
* v1.3.0 24-Mar-1995 Added the ability to set default translator via app name.
* v1.3.1 28-Mar-1995 Updated SpinCursor() to not rely on specific resource ids.
* v1.3.2 31-Mar-1995 Added check for max output filename length.
* v1.4.0 11-Apr-1995 Added DeleteRF() and Touch().
* v1.5.0 25-Apr-1995 Added TickleParentDir(), ScrollIcon(), and Progress().
* v1.6.0 01-Jun-1995 Added basic apple event support.
* v1.7.0 13-Jun-1995 Added GetFileOSType() and the ability to Touch any file.
* v1.7.1 15-Jun-1995 Added splash screen on kAEOpenApplication event, adjusted how
* gAutoQuit works, and made the progress bar black & white.
* v1.8.0 16-Jun-1995 Added TypeCreator() and related routines.
* v1.8.1 18-Jun-1995 Added better handling of filename conflicts.
* v1.9.0 25-Jun-1995 Added the ability to select a filter at the time files are
* dragged to the app (when the option key is held down).
* v1.9.1 30-Jun-1995 Touch() now always sets seconds to zero.
* v2.0.0 01-Jul-1995 Renamed to Acme Filters. Added Tab2Space().
* v2.0.1 28-Jul-1995 Rewrote Rot13() algorithm.
* v2.1.0 12-Oct-1995 Rot13() and Tab2Space() now replace the original file instead
* of creating a duplicate with .r13 or .t2s suffixes. Default
* filter can now be set via the keyboard (1 thru 6). Cancel
* requests are now handled more reliably.
* v2.2.0 03-Nov-1995 Added MacDosUnix() and related routines.
* v2.2.2 16-Nov-1995 Touch() can now specify creation and modification dates.
* Removed MacDosUnix() because I couldn't get it to work right.
* v2.3.0 02-Feb-1996 Progress window is now movable-modal and its position is
* saved and restored between launches. Added FindOriginal().
* v2.3.1 12-Feb-1996 Improved progress window updating. Rewrote FindOriginal().
* v2.3.2 16-Feb-1996 FindOriginal() now also handles folders.
*
* Functions: main()
* GetOurProcessInfo()
* SetupMenuBar()
* HandleEvent()
* HandleKeyDown()
* HandleMouseDown()
* HandleMenuChoice()
* HandleAppleMenu()
* HandleFileMenu()
* GetFileSpec()
* FSpfopen()
* TickleParentDir()
* GetFileOSType()
* GetFSSpecType()
* AboutBox()
* AboutBoxDlgFltr()
* CenterString()
* pstrcat()
* pstrcpy()
* Cancel()
* SpinCursor()
* ScrollIcon()
* Progress()
* FrameBar()
* LoadWindowPrefs()
* SaveWindowPrefs()
* ChooseDefault()
* ChooseDefaultDlgFltr()
* LoadFilterPrefs()
* SaveFilterPrefs()
* SpecialKeyDown()
**********************************************************************************************/
/************ I N C L U D E F I L E S *******************************************************/
#include <stdio.h>
#include <string.h>
#include <Files.h>
#include <Icons.h>
#include "Acme Filters.h"
#include "Acme Filters AE.h"
#include "ASCToMac.h"
#include "Delete RF.h"
#include "FindOriginal.h"
#include "Rot13.h"
#include "Tab2Space.h"
#include "Touch.h"
#include "TypeCreator.h"
/************ G L O B A L V A R I A B L E S *************************************************/
Str32 gAppName;
MenuHandle gAppleMenu, gFileMenu;
char gConversionType;
Boolean gQuit = false, gAutoQuit = true;
DialogPtr gProgressDlog = (DialogPtr)0L;
Boolean gFromMenu = false;
Boolean gCancelReq;
/**********************************************************************************************
* Function Name: main
*
* Description: Standard stuff.
*
* Parameters: None.
*
* Return Value: None.
**********************************************************************************************/
void main( void )
{
EventRecord event;
InitGraf( &qd.thePort );
InitFonts();
FlushEvents( everyEvent, 0 );
InitWindows();
InitMenus();
TEInit();
InitDialogs( 0 );
InitCursor();
GetOurProcessInfo();
SetupMenuBar();
InstallAEHandlers();
while ( !gQuit )
{
SetCursor( &qd.arrow );
HandleEvent( &event );
}
}
/**********************************************************************************************
* Function Name: GetOurProcessInfo
*
* Description: Get our app's name.
*
* Parameters: None.
*
* Return Value: None.
**********************************************************************************************/
void GetOurProcessInfo( void )
{
OSErr err;
long response;
ProcessSerialNumber psn;
ProcessInfoRec info;
FSSpec fsp;
// this app requires system 7 or above
err = Gestalt( gestaltSystemVersion, &response );
if ( err || ((response & 0xFFFF) < kSystemSeven) )
{
SysBeep( 1 );
ExitToShell();
}
// get our app's name
GetCurrentProcess( &psn );
info.processInfoLength = sizeof( ProcessInfoRec );
info.processName = gAppName;
info.processAppSpec = &fsp;
GetProcessInformation( &psn, &info );
// load the default conversion type
gConversionType = LoadFilterPrefs();
}
/**********************************************************************************************
* Function Name: SetupMenuBar
*
* Description: Standard stuff.
*
* Parameters: None.
*
* Return Value: None.
**********************************************************************************************/
void SetupMenuBar( void )
{
short i;
Str255 aboutStr;
SetMenuBar( GetNewMBar( kBaseResID ) );
gAppleMenu = GetMHandle( kAppleMenuID );
gFileMenu = GetMHandle( kFileMenuID );
// give the filters command-key equivalents
for ( i = kASCToMac; i <= kTypeCreator; i++ )
SetItemCmd( gFileMenu, i, i+'0' );
// put our app's name in the about menu
pstrcpy( aboutStr, "¥pAbout " );
pstrcat( aboutStr, gAppName );
pstrcat( aboutStr, "¥pノ" );
SetItem( gAppleMenu, kAboutItem, aboutStr );
AddResMenu( gAppleMenu, 'DRVR' );
DrawMenuBar();
}
/**********************************************************************************************
* Function Name: HandleEvent
*
* Description: Standard stuff.
*
* Parameters: event - the event record to process.
*
* Return Value: None.
**********************************************************************************************/
void HandleEvent( EventRecord *event )
{
WaitNextEvent( everyEvent, event, 15L, nil );
switch ( event->what )
{
case keyDown:
HandleKeyDown( event );
break;
case mouseDown:
HandleMouseDown( event );
break;
case kHighLevelEvent:
AEProcessAppleEvent( event );
break;
}
}
/**********************************************************************************************
* Function Name: HandleKeyDown
*
* Description: Standard stuff.
*
* Parameters: event - the event record.
*
* Return Value: None.
**********************************************************************************************/
void HandleKeyDown( EventRecord *event )
{
if ( (event->modifiers & cmdKey) )
{
HandleMenuChoice( MenuKey( event->message & charCodeMask ) );
}
}
/**********************************************************************************************
* Function Name: HandleMouseDown
*
* Description: Standard stuff.
*
* Parameters: event - the event record.
*
* Return Value: None.
**********************************************************************************************/
void HandleMouseDown( EventRecord *event )
{
WindowPtr whichWindow;
switch ( FindWindow( event->where, &whichWindow ) )
{
case inMenuBar:
HandleMenuChoice( MenuSelect( event->where ) );
break;
}
}
/**********************************************************************************************
* Function Name: HandleMenuChoice
*
* Description: Standard stuff.
*
* Parameters: choice - hi word contains menu number, lo word contains menu item.
*
* Return Value: None.
**********************************************************************************************/
void HandleMenuChoice( long choice )
{
short menu;
short item;
if ( choice )
{
menu = HiWord( choice );
item = LoWord( choice );
switch ( menu )
{
case kAppleMenuID:
HandleAppleMenu( item );
break;
case kFileMenuID:
HandleFileMenu( item );
break;
}
}
HiliteMenu( 0 );
}
/**********************************************************************************************
* Function Name: HandleAppleMenu
*
* Description: Standard stuff.
*
* Parameters: item - the menu item selected.
*
* Return Value: None.
**********************************************************************************************/
void HandleAppleMenu( short item )
{
Str255 name;
switch ( item )
{
case kAboutItem:
AboutBox( kAboutTimeOut );
break;
default:
GetItem( gAppleMenu, item, name );
OpenDeskAcc( name );
break;
}
}
/**********************************************************************************************
* Function Name: HandleFileMenu
*
* Description: Standard stuff.
*
* Parameters: item - the menu item selected.
*
* Return Value: None.
**********************************************************************************************/
void HandleFileMenu( short item )
{
OSType type;
FSSpec file;
// only allow these file types to be processed
switch ( item )
{
case kASCToMac:
case kDeleteRF:
case kRot13:
case kTab2Space:
type = kTEXTType;
break;
case kFindOriginal:
case kTouch:
case kTypeCreator:
type = kAnyType;
break;
}
if ( item == kQuitItem )
{
gQuit = true;
}
else if ( item == kPrefsItem )
{
ChooseDefault( true );
}
else if ( GetFileSpec( &file, type ) == noErr )
{
ProcessSerialNumber psn = { 0, kCurrentProcess };
AEAddressDesc address;
AppleEvent event;
AEDescList docList;
// set the conversion type
gConversionType = item;
gFromMenu = true;
// get our address
AECreateDesc( typeProcessSerialNumber, &psn, sizeof( ProcessSerialNumber ), &address );
// create a new apple event to send to ourselves
AECreateAppleEvent( kCoreEventClass, kAEOpenDocuments, &address, kAutoGenerateReturnID, kAnyTransactionID, &event );
// create an empty list
AECreateList( (Ptr)0, (Size)0, false, &docList );
// put the file spec in the list
AEPutPtr( &docList, 1, typeFSS, &file, sizeof( FSSpec ) );
// put the list in the apple event
AEPutParamDesc( &event, keyDirectObject, &docList );
// send the event
AESend( &event, nil, kAEWaitReply, kAENormalPriority, kAEDefaultTimeout, nil, nil );
// clean up
AEDisposeDesc( &address );
AEDisposeDesc( &event );
AEDisposeDesc( &docList );
}
}
/**********************************************************************************************
* Function Name: GetFileSpec
*
* Description: Ask the user for a file.
*
* Parameters: file - the file spec of the file.
* type - the type of file to list (e.g. 'TEXT', '****').
*
* Return Value: noErr if ok, error code otherwise.
**********************************************************************************************/
OSErr GetFileSpec( FSSpec *file, OSType type )
{
OSErr err = -1;
Point where = { 0, 0 };
SFTypeList typeList;
short numTypes = (type == kAnyType) ? -1 : 1;
StandardFileReply reply;
typeList[0] = type;
StandardGetFile( nil, numTypes, typeList, &reply );
if ( reply.sfGood )
{
*file = reply.sfFile;
err = noErr;
}
return ( err );
}
/**********************************************************************************************
* Function Name: FSpfopen
*
* Description: Open a file from an FSSpec using fopen.
*
* Parameters: spec - the FSSpec containing the info we need.
*
* Return Value: A file pointer to the opened file, nil if error.
**********************************************************************************************/
FILE *FSpfopen( FSSpec *spec, char *mode )
{
short vRefNum;
long parID;
char name[64];
short oldVol;
FILE *fp = nil;
vRefNum = spec->vRefNum;
parID = spec->parID;
BlockMove( &spec->name[1], name, spec->name[0] );
name[spec->name[0]] = '¥0';
if ( GetVol( nil, &oldVol ) == noErr )
{
if ( HSetVol( nil, vRefNum, parID ) == noErr )
{
fp = fopen( name, mode );
}
SetVol( nil, oldVol );
}
return ( fp );
}
/**********************************************************************************************
* Function Name: TickleParentDir
*
* Description: Update the file's parent directory modification date so changes to the
* file appear immediately.
*
* Parameters: file - a pointer to the FSSpec of the file.
*
* Return Value: None.
**********************************************************************************************/
void TickleParentDir( FSSpec *file )
{
CInfoPBRec pb;
pb.dirInfo.ioCompletion = 0;
pb.dirInfo.ioNamePtr = 0;
pb.dirInfo.ioVRefNum = file->vRefNum;
pb.dirInfo.ioFDirIndex = -1;
pb.dirInfo.ioDrDirID = file->parID;
PBGetCatInfoSync( &pb );
GetDateTime( &pb.dirInfo.ioDrMdDat );
PBSetCatInfoSync( &pb );
}
/**********************************************************************************************
* Function Name: GetFileOSType
*
* Description: Get the file's Finder info and return the type.
*
* Parameters: file - a pointer to the FSSpec of the file.
*
* Return Value: The type of the file.
**********************************************************************************************/
OSType GetFileOSType( FSSpec *file )
{
FInfo info;
// get the file's Finder info
FSpGetFInfo( file, &info );
return ( info.fdType );
}
/**********************************************************************************************
* Function Name: GetFSSpecType
*
* Description: Determine if an FSSpec is a file or a folder.
*
* Parameters: spec - a file system specification.
*
* Return Value: 0 = folder, 1 = file.
**********************************************************************************************/
short GetFSSpecType( FSSpec *spec )
{
CInfoPBRec pb;
pb.hFileInfo.ioVRefNum = spec->vRefNum;
pb.hFileInfo.ioDirID = spec->parID;
pb.hFileInfo.ioNamePtr = spec->name;
pb.hFileInfo.ioFDirIndex = 0;
PBGetCatInfoSync( &pb );
// 0 = folder, 1 = file
return ( ((char)(pb.hFileInfo.ioFlAttrib) & (char)0x10) ? 0 : 1 );
}
/**********************************************************************************************
* Function Name: AboutBox
*
* Description: Gimme some credit.
*
* Parameters: hangTime - dismiss the dialog after this many seconds.
*
* Return Value: None.
**********************************************************************************************/
void AboutBox( short hangTime )
{
DialogPtr aboutBox;
WindowPtr saveMe;
Boolean done = false;
short item;
ModalFilterUPP filter = NewModalFilterProc( AboutBoxDlgFltr );
static unsigned char line0[] = "¥pDonna's word processor file converter";
static unsigned char line1[] = "¥p(and other assorted filters)";
static unsigned char line2[] = "¥pby Eric V. Curtis (boston84@aol.com)";
if ( aboutBox = GetNewDialog( kAboutBoxDlog, nil, (WindowPtr)-1L ) )
{
GetPort( &saveMe );
SetPort( aboutBox );
ShowWindow( aboutBox );
TextFont( geneva );
TextSize( 24 );
TextFace( bold );
MoveTo( CenterString( &aboutBox->portRect, gAppName ), 30 );
DrawString( gAppName );
TextSize( 9 );
MoveTo( CenterString( &aboutBox->portRect, line0 ), 52 );
DrawString( line0 );
MoveTo( CenterString( &aboutBox->portRect, line1 ), 64 );
DrawString( line1 );
TextFace( normal );
MoveTo( CenterString( &aboutBox->portRect, line2 ), 123 );
DrawString( line2 );
MoveTo( aboutBox->portRect.left + kInset, 106 );
DrawString( kDate );
MoveTo( aboutBox->portRect.right - 60 - kInset, 106 );
DrawString( kVersion );
SetWRefCon( aboutBox, TickCount() + (hangTime * 60) );
while ( done == false )
{
ModalDialog( filter, &item );
switch( item )
{
case kAboutItem:
done = true;
break;
}
}
SetPort( saveMe );
DisposDialog( aboutBox );
}
}
/**********************************************************************************************
* Function Name: AboutBoxDlgFltr
*
* Description: Clicking anywhere or pressing any key dismisses the dialog.
*
* Parameters: dialog - the dialog being filtered.
* event - the event record being processed.
* item - the item in which the event occured.
*
* Return Value: true - Tells ModalDialog to return immediately and not handle the event.
* false - Tells ModalDialog to handle the event normally.
**********************************************************************************************/
pascal Boolean AboutBoxDlgFltr( DialogPtr dialog, EventRecord *event, short *item )
{
Boolean result = false;
if ( (event->what == keyDown) || (event->what == mouseDown) || (TickCount() >= GetWRefCon( dialog )) )
{
*item = kAboutItem;
result = true;
}
return ( result );
}
/**********************************************************************************************
* Function Name: CenterString
*
* Description: Center a string horizontally in a rectangle.
*
* Parameters: rect - the rectangle.
* string - the string to be centered.
*
* Return Value: the horizontal offset to center the string.
**********************************************************************************************/
short CenterString( Rect *rect, Str255 string )
{
return ( ((rect->right - rect->left - StringWidth( string )) / 2) + 1 );
}
/**********************************************************************************************
* Function Name: pstrcat
*
* Description: Catenate two pascal strings. The first string is replaced with the
* catenation of the first and second strings. If the total length of both
* strings is more than 255, the second string gets truncated.
*
* Note: Str255 is defined as: typedef unsigned char Str255[256].
*
* Parameters: s1, s2 - the pascal strings to catenate.
*
* Return Value: s1 contains the catenation of s1 and s2.
* true if second string was truncated, false otherwise.
**********************************************************************************************/
Boolean pstrcat( Str255 s1, Str255 s2 )
{
Boolean truncated = false;
// truncate the 2nd string if necessary
if ( *s1 + *s2 > 255 )
{
*s2 = 255 - *s1;
truncated = true;
}
// catenate the strings
BlockMove( s2+1, s1+(*s1)+1, *s2 );
*s1 += *s2;
return ( truncated );
}
/**********************************************************************************************
* Function Name: pstrcpy
*
* Description: Copy the pascal string src to the pascal string dst.
*
* Parameters: dst, src - the destination and source strings.
*
* Return Value: None.
**********************************************************************************************/
void pstrcpy( Str255 dst, Str255 src )
{
BlockMove( src, dst, (*src)+1 );
}
/**********************************************************************************************
* Function Name: Cancel
*
* Description: Let the user cancel a conversion in progress.
*
* Parameters: None.
*
* Return Value: true if cancel, false otherwise.
**********************************************************************************************/
Boolean Cancel( void )
{
EventRecord event;
Boolean cancel = false;
static doit = 0;
if ( WaitNextEvent( everyEvent, &event, 1, nil ) )
{
switch ( event.what )
{
case updateEvt:
if ( (WindowPtr)event.message == gProgressDlog )
{
BeginUpdate( gProgressDlog );
DrawDialog( gProgressDlog );
EndUpdate( gProgressDlog );
}
break;
case keyDown:
case autoKey:
if ( (event.modifiers & cmdKey) && ((event.message & charCodeMask) == kPeriod) )
{
cancel = true;
}
break;
case mouseDown:
{
WindowPtr window;
if ( FindWindow( event.where, &window ) == inDrag )
{
DragWindow( window, event.where, &(**GetGrayRgn()).rgnBBox );
SaveWindowPrefs( gProgressDlog );
}
}
break;
}
}
return ( cancel );
}
/**********************************************************************************************
* Function Name: SpinCursor
*
* Description: Spin the cursor while work is being done.
*
* Parameters: None.
*
* Return Value: None.
**********************************************************************************************/
void SpinCursor( void )
{
static short id = 1;
CursHandle cursH;
if ( cursH = (CursHandle)Get1IndResource( kCursorType, id ) )
{
HLock( (Handle)cursH );
SetCursor( *cursH );
ReleaseResource( (Handle)cursH );
}
id++;
if ( id > Count1Resources( kCursorType ) ) id = 1;
}
/**********************************************************************************************
* Function Name: ScrollIcon
*
* Description: Scroll the application icon while work is being done.
*
* Parameters: None.
*
* Return Value: None.
**********************************************************************************************/
void ScrollIcon( void )
{
static short offset = 0;
WindowPtr oldPort;
short iType;
Handle iHandle;
Rect iRect;
RgnHandle rgnH = NewRgn();
if ( gProgressDlog )
{
GetPort( &oldPort );
SetPort( gProgressDlog );
GetClip( rgnH );
GetDItem( gProgressDlog, kSpinItem, &iType, &iHandle, &iRect );
ClipRect( &iRect );
OffsetRect( &iRect, 0, -offset );
PlotIconID( &iRect, atNone, ttNone, kBaseResID );
OffsetRect( &iRect, 0, kIconHeight+kIconSpace );
PlotIconID( &iRect, atNone, ttNone, kBaseResID );
OffsetRect( &iRect, 0, -kIconSpace );
iRect.bottom = iRect.top + kIconSpace;
EraseRect( &iRect );
offset++;
if ( offset > kIconHeight ) offset = 0;
ClipRect( &(**rgnH).rgnBBox );
DisposeRgn( rgnH );
SetPort( oldPort );
}
}
/**********************************************************************************************
* Function Name: Progress
*
* Description: Create, update, and destroy the progress dialog.
*
* Parameters: what - what to do.
* remain - how many files to go.
* name - the filename.
* percent - how much to fill the progress bar.
*
* Return Value: None.
**********************************************************************************************/
void Progress( short what, short remain, Str255 name, short percent )
{
WindowPtr oldPort;
Rect tRect;
Str255 tStr;
short iType;
Handle iHandle;
static Rect iRect, bar;
static float limit;
switch ( what )
{
case eCreate:
if ( gProgressDlog )
DisposDialog( gProgressDlog );
gProgressDlog = GetNewDialog( kProgressDlog, nil, kMoveToFront );
if ( gProgressDlog )
{
GetPort( &oldPort );
SetPort( gProgressDlog );
LoadWindowPrefs( gProgressDlog );
ShowWindow( gProgressDlog );
GetItem( gFileMenu, gConversionType, tStr );
if ( (char)tStr[tStr[0]] == kEllipsis ) tStr[0]--;
SetWTitle( gProgressDlog, tStr );
GetDItem( gProgressDlog, kRemainItem, &iType, &iHandle, &tRect );
NumToString( remain, tStr );
SetIText( iHandle, tStr );
GetDItem( gProgressDlog, kProgBarItem, &iType, &iHandle, &iRect );
SetDItem( gProgressDlog, kProgBarItem, iType, (Handle)&FrameBar, &iRect );
bar = iRect;
limit = (float)(bar.right - bar.left) / 100.0;
InsetRect( &bar, 1, 1 );
bar.right = bar.left;
SetWRefCon( gProgressDlog, (long)&bar );
DrawDialog( gProgressDlog );
SetPort( oldPort );
}
break;
case eFileName:
if ( gProgressDlog )
{
GetPort( &oldPort );
SetPort( gProgressDlog );
GetDItem( gProgressDlog, kFileNameItem, &iType, &iHandle, &tRect );
SetIText( iHandle, name );
SetPort( oldPort );
}
break;
case eRemainPercent:
if ( gProgressDlog )
{
GetPort( &oldPort );
SetPort( gProgressDlog );
GetDItem( gProgressDlog, kRemainItem, &iType, &iHandle, &tRect );
NumToString( remain, tStr );
SetIText( iHandle, tStr );
if ( percent < 0 ) percent = 0;
if ( percent > 100 ) percent = 100;
bar.right = bar.left + (percent * limit);
if ( bar.right >= iRect.right ) bar.right = iRect.right-1;
FillRect( &bar, &qd.gray );
SetPort( oldPort );
}
break;
case eDelete:
if ( gProgressDlog )
{
HideWindow( gProgressDlog );
DisposDialog( gProgressDlog );
gProgressDlog = 0;
}
break;
}
}
/**********************************************************************************************
* Function Name: FrameBar
*
* Description: Draw the progress bar when it needs updating.
*
* Parameters: Standard stuff.
*
* Return Value: None.
**********************************************************************************************/
pascal void FrameBar( WindowPtr dialog, short item )
{
short iType;
Handle iHandle;
Rect iRect;
GetDItem( dialog, item, &iType, &iHandle, &iRect );
FrameRect( &iRect );
FillRect( (Rect *)GetWRefCon( dialog ), &qd.gray );
}
/**********************************************************************************************
* Function Name: LoadWindowPrefs
*
* Description: Move the progress dialog into position.
*
* Parameters: window - the window to be moved.
*
* Return Value: None.
**********************************************************************************************/
void LoadWindowPrefs( WindowPtr window )
{
Point **locationH;
if ( locationH = (Point **)GetResource( 'Pref', kBaseResID+1 ) )
{
if ( PtInRect( **locationH, &(**GetGrayRgn()).rgnBBox ) )
{
MoveWindow( window, (**locationH).h, (**locationH).v, true );
}
ReleaseResource( (Handle)locationH );
}
}
/**********************************************************************************************
* Function Name: SaveWindowPrefs
*
* Description: Remember the progress dialog's position.
*
* Parameters: window - the window of interest.
*
* Return Value: None.
**********************************************************************************************/
void SaveWindowPrefs( WindowPtr window )
{
Point **locationH, topLeft;
WindowPtr oldPort;
if ( locationH = (Point **)GetResource( 'Pref', kBaseResID+1 ) )
{
GetPort( &oldPort );
SetPort( window );
topLeft = *(Point *)&window->portRect;
LocalToGlobal( &topLeft );
if ( ((**locationH).h != topLeft.h) || ((**locationH).v != topLeft.v) )
{
**locationH = topLeft;
ChangedResource( (Handle)locationH );
}
ReleaseResource( (Handle)locationH );
SetPort( oldPort );
}
}
/**********************************************************************************************
* Function Name: ChooseDefault
*
* Description: Let the user set the default filter to be used.
*
* Parameters: save - true for perm, false for temp.
*
* Return Value: noErr if ok, error code if canceled.
**********************************************************************************************/
OSErr ChooseDefault( Boolean save )
{
OSErr err = noErr;
DialogPtr picker;
WindowPtr saveMe;
Boolean done = false;
short item;
ModalFilterUPP filter = NewModalFilterProc( ChooseDefaultDlgFltr );
short i;
short iType;
Handle iHandle;
Rect iRect;
Str255 str;
long ticks;
if ( picker = GetNewDialog( kDefaultDlog, nil, (WindowPtr)-1L ) )
{
GetPort( &saveMe );
SetPort( picker );
ShowWindow( picker );
// draw a divider line
GetDItem( picker, kDivider, &iType, &iHandle, &iRect );
FrameRect( &iRect );
// de-activate and name each radio button
for ( i = kASCToMac+2; i <= kTypeCreator+2; i++ )
{
GetDItem( picker, i, &iType, &iHandle, &iRect );
SetCtlValue( (ControlHandle)iHandle, 0 );
GetItem( gFileMenu, i-2, str );
if ( (char)(str[str[0]]) == kEllipsis ) str[0]--;
SetCTitle( (ControlHandle)iHandle, str );
}
// activate the radio button of the currently selected filter
gConversionType = LoadFilterPrefs();
GetDItem( picker, gConversionType+2, &iType, &iHandle, &iRect );
SetCtlValue( (ControlHandle)iHandle, 1 );
while ( !done )
{
ModalDialog( filter, &item );
switch( item )
{
case -1: // -1 + 1 = 0, ok
case -2: // -2 + 1 = -1, cancel
err = item + 1;
done = true;
break;
default:
// adjust the radio buttons
GetDItem( picker, gConversionType+2, &iType, &iHandle, &iRect );
SetCtlValue( (ControlHandle)iHandle, 0 );
GetDItem( picker, item, &iType, &iHandle, &iRect );
SetCtlValue( (ControlHandle)iHandle, 1 );
Delay( 6, &ticks );
// remember the new filter index
gConversionType = item-2;
if ( save ) SaveFilterPrefs( gConversionType );
done = true;
break;
}
}
SetPort( saveMe );
DisposDialog( picker );
}
return ( err );
}
/**********************************************************************************************
* Function Name: ChooseDefaultDlgFltr
*
* Description: Handle mouse and keystrokes.
*
* Parameters: dialog - the dialog being filtered.
* event - the event record being processed.
* item - the item in which the event occured.
*
* Return Value: true - ModalDialog returns immediately and without handling the event.
* false - ModalDialog handles the event normally.
**********************************************************************************************/
pascal Boolean ChooseDefaultDlgFltr( DialogPtr dialog, EventRecord *event, short *item )
{
#pragma unused ( dialog )
char c;
Boolean result = false;
if ( (event->what == keyDown) || (event->what == autoKey) )
{
c = event->message & charCodeMask;
if ( (c == kEnter) || (c == kReturn) )
{
*item = -1;
result = true;
}
if ( (c == kEscape) || ((event->modifiers & cmdKey) && (c == kPeriod)) )
{
*item = -2;
result = true;
}
if ( (c >= '0'+kASCToMac) && (c <= '0'+kTypeCreator) )
{
*item = c - '0' + 2;
result = true;
}
}
return ( result );
}
/**********************************************************************************************
* Function Name: LoadFilterPrefs
*
* Description: Get the default conversion type.
*
* Parameters: None.
*
* Return Value: pref - the default conversion type index.
**********************************************************************************************/
char LoadFilterPrefs( void )
{
char **prefH, pref = 1;
if ( prefH = (char **)Get1Resource( kPrefType, kBaseResID ) )
{
pref = **prefH;
ReleaseResource( (Handle)prefH );
}
return ( pref );
}
/**********************************************************************************************
* Function Name: SaveFilterPrefs
*
* Description: Set the default conversion type.
*
* Parameters: pref - the default conversion type index.
*
* Return Value: None.
**********************************************************************************************/
void SaveFilterPrefs( char pref )
{
char **prefH;
if ( prefH = (char **)Get1Resource( kPrefType, kBaseResID ) )
{
**prefH = pref;
ChangedResource( (Handle)prefH );
WriteResource( (Handle)prefH );
ReleaseResource( (Handle)prefH );
}
}
/**********************************************************************************************
* Function Name: SpecialKeyDown
*
* Description: Check to see if a certain key is down.
*
* Parameters: key - a key code.
*
* Return Value: true if key is down, false otherwise.
**********************************************************************************************/
Boolean SpecialKeyDown( unsigned short key )
{
KeyMap km;
unsigned char *akm = (unsigned char *)&km;
GetKeys( km );
return ( (akm[key>>3] >> (key & 7)) & 1 );
}